package com.slipper.bpmn.dealer.support;

import com.slipper.constants.FlowConstants;
import com.slipper.bpmn.BpmnEngine;
import com.slipper.bpmn.dealer.INodeDealer;
import com.slipper.bpmn.vo.BpmnVO;
import com.slipper.system.flow.bo.FlowInstBO;
import com.slipper.system.flow.bo.FlowInstNodeBO;
import com.slipper.system.flow.bo.FlowNodeBO;
import com.slipper.system.flow.service.FlowInstNodeService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Component;

/**
 * 并行结束节点处理器
 */
@Component
public class ParallelEndNodeDealer implements INodeDealer {
    @Resource
    private FlowInstNodeService flowInstNodeService;
    @Resource
    private BpmnEngine bpmnEngine;
    
    @Override
    public String[] getTypes() {
        return new String[] { "31" };
    }

    @Override
    public FlowInstNodeBO doDeal(
            int dealCnt,
            boolean finished,
            FlowNodeBO flowNode,
            FlowInstBO flowInst,
            FlowInstNodeBO preInstNode,
            FlowInstNodeBO currInstNode,
            BpmnVO vo) {
        if (currInstNode == null) {
            currInstNode = this.createInstData(flowNode, flowInst, preInstNode, vo, true);
        } else {
            currInstNode = flowInstNodeService.queryBy(currInstNode.getId());
            currInstNode.setDealManId(vo.getCurrEmpId());
            currInstNode.setDealOrgId(vo.getCurrOrgId());
            currInstNode.setDealStatus(FlowConstants.FlowInstNode.DEAL_STATUS_FINISHED);
            flowInstNodeService.save(currInstNode);
        }
        
        FlowInstNodeBO parallelNode = this.bpmnEngine.findPreParallelInstNode(currInstNode.getPreInstNodeId(), 0);
        if (parallelNode == null) {
            throw new RuntimeException("找不到相应的并发节点！");
        }
        if (parallelNode.getMergeCnt() == null) {
            parallelNode.setMergeCnt(1);
        } else {
            parallelNode.setMergeCnt(parallelNode.getMergeCnt() + 1);
        }
        
        if (parallelNode.getMergeCnt() >= parallelNode.getParallelCnt()) {
            bpmnEngine.next(dealCnt + 1, flowNode, flowInst, currInstNode);
        }

        flowInstNodeService.save(parallelNode);
        return currInstNode;
    }

    public FlowInstNodeBO createInstData(
            FlowNodeBO flowNode,
            FlowInstBO flowInst,
            FlowInstNodeBO preInstNode,
            BpmnVO vo,
            boolean finished) {
        // 节点实例化
        FlowInstNodeBO flowInstNode = new FlowInstNodeBO();
        flowInstNode.setInstId(flowInst.getId());
        flowInstNode.setPreInstNodeId(preInstNode.getId());
        flowInstNode.setCurrFlowNodeId(flowNode.getId());
        flowInstNode.setLineId(flowNode.getInLineId());
        flowInstNode.setDealManId(vo.getCurrEmpId());
        flowInstNode.setDealOrgId(vo.getCurrOrgId());
        flowInstNode.setStartTime(System.currentTimeMillis());
        flowInstNode.setEndTime(System.currentTimeMillis());
        flowInstNode.setUpdateTime(System.currentTimeMillis());
        flowInstNode.setCreateTime(System.currentTimeMillis());

        if (!finished) {
            flowInstNode.setDealStatus(FlowConstants.FlowInstNode.DEAL_STATUS_PENDING);
        } else {
            flowInstNode.setEndTime(System.currentTimeMillis());
            flowInstNode.setDealStatus(FlowConstants.FlowInstNode.DEAL_STATUS_FINISHED);
        }

        flowInstNodeService.save(flowInstNode);
        return flowInstNode;
    }
}
